﻿using Ch9_Portable.Interfaces;
using Ch9_Portable.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace Ch9RSS_WP8.Services
{
    public class SavedDataService : IDeviceDataService
    {
        private bool isServiceRemoteEnabled = false;
        public bool IsRemoteEnabled()
        {
            return isServiceRemoteEnabled;
        }
        public void SetIsRemoteEnabled(bool enabled)
        {
            isServiceRemoteEnabled = enabled;
        }

        // this should probably be a global object so all ViewModels
        //   can access it
        public SavedDataService()
        {
            //Windows.Storage.ApplicationData.Current.DataChanged += Current_DataChanged;
            if (isServiceRemoteEnabled)
                LoadRoamingSessions(roamingSessionsFile);
            else
                LoadLocalSessions(localSessionFile);
        }

        void Current_DataChanged(Windows.Storage.ApplicationData sender, object args)
        {
            LoadRoamingSessions(roamingSessionsFile);
        }

        public async Task<List<Ch9Item>> LoadSavedData()
        {
            if (isServiceRemoteEnabled)
            {
                if (RoamingSessions == null)
                    RoamingSessions = await LoadRoamingSessions(roamingSessionsFile);
                return RoamingSessions;
            }
            else
            {
                if (LocalSessions == null)
                    LocalSessions = await LoadLocalSessions(localSessionFile);
                return LocalSessions;
            }
        }

        public List<Ch9Item> LocalSessions { get; private set; }
        public List<Ch9Item> RoamingSessions { get; private set; }
        protected string localSessionFile = "localSessions.json";
        protected string roamingSessionsFile = "roamingSessions.json";

        // Use this method for a session that has already been saved
        //   locally
        public async Task<bool> SaveLocalSession(Ch9Item item)
        {
            if (LocalSessions == null)
                LocalSessions = new List<Ch9Item>();
            LocalSessions.Insert(0, item);
            await SaveLocalSessions(localSessionFile);
            return true;
        }

        // Use for loading all local sessions
        public async Task<List<Ch9Item>> LoadLocalSessions(string fileName)
        {
            try
            {
                var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
                var sessionfile = await localFolder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists);
                var serializer = new DataContractSerializer(typeof(List<Ch9Item>));
                List<Ch9Item> returnList;

                using (Stream s = await sessionfile.OpenStreamForReadAsync())
                {
                    returnList = (List<Ch9Item>)serializer.ReadObject(s);
                }
                LocalSessions = returnList;
                return returnList;
            }
            catch (Exception ex)
            {
                LocalSessions = new List<Ch9Item>();
                return LocalSessions;
            }
        }

        private async Task SaveLocalSessions(string fileName)
        {
            var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            var sessionfile = await localFolder.CreateFileAsync(fileName, Windows.Storage.CreationCollisionOption.OpenIfExists);
            var serializer = new DataContractSerializer(typeof(List<Ch9Item>));
            using (Stream s = await sessionfile.OpenStreamForWriteAsync())
            {
                serializer.WriteObject(s, LocalSessions);
            }
        }

        // Check to see if a session has been saved 
        public bool HasSavedSession(Ch9Item thisSession)
        {
            if (isServiceRemoteEnabled && RoamingSessions != null)
            {
                var existingItem = RoamingSessions.FirstOrDefault(ch9 => ch9.guid == thisSession.guid);
                bool hasSession = existingItem == null ? false : true;
                return hasSession;
            }
            else if (LocalSessions != null)
            {
                var existingItem = LocalSessions.FirstOrDefault(ch9 => ch9.guid == thisSession.guid);
                bool hasSession = existingItem == null ? false : true;
                return hasSession;
            }
            return false;
        }

        // Use for saving a session to remote storage
        //   this should be used only when the session is
        //   "live"
        public async Task<bool> SaveRoamingSession(Ch9Item session)
        {
            // If we already have a copy of thie item in our roaming data
            Ch9Item existingItem = null;
            if (RoamingSessions == null)
                await LoadRoamingSessions(roamingSessionsFile);
            foreach (Ch9Item ch9 in RoamingSessions)
            {
                if (session.guid == ch9.guid)
                    existingItem = ch9;
            }
            //var existingItem = RoamingSessions.FirstOrDefault(ch9 => ch9.guid == session.guid);
            // get rid of it (so we can replace it with the updated item)
            if (existingItem != null)
                RoamingSessions.Remove(existingItem);

            // Insert the new item at the top
            RoamingSessions.Insert(0, session);

            // trying to limit out roaming data to 20 items
            // if we were really smart, we'd push these > 20 items into
            // local storage
            while (RoamingSessions.Count > 20)
            {
                RoamingSessions.RemoveAt(RoamingSessions.Count - 1);
            }
            await SaveRoamingSessions(roamingSessionsFile);
            return true;
        }

        public async Task SaveRoamingSessions(string filename)
        {
            var roamingFolder = Windows.Storage.ApplicationData.Current.RoamingFolder;
            var sessionfile = await roamingFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.OpenIfExists);
            var serializer = new DataContractSerializer(typeof(List<Ch9Item>));
            using (Stream s = await sessionfile.OpenStreamForWriteAsync())
            {
                serializer.WriteObject(s, RoamingSessions);
            }
        }

        // get a list of all recent sessions (saved as a json)
        public async Task<List<Ch9Item>> LoadRoamingSessions(string filename)
        {
            try
            {
                var roamingFolder = Windows.Storage.ApplicationData.Current.RoamingFolder;
                var sessionfile = await roamingFolder.CreateFileAsync(filename, Windows.Storage.CreationCollisionOption.OpenIfExists);
                var serializer = new DataContractSerializer(typeof(List<Ch9Item>));
                List<Ch9Item> returnList;
                using (Stream s = await sessionfile.OpenStreamForReadAsync())
                {
                    returnList = (List<Ch9Item>)serializer.ReadObject(s);
                }
                RoamingSessions = returnList;
                return returnList;
            }
            catch (Exception ex)
            {
                RoamingSessions = new List<Ch9Item>();
                return RoamingSessions;
            }
        }


    }
}
